這邊是語言的貼身教練,在你把文章打好,要放上去之前,教練會先對內容看看語句是否通暢。
句子 | 錯誤 |
---|---|
好嗎你? | ReferenceError |
真的。長大了, | SyntaxError |
都變型男了! | TypeError |
主要是 JavaScript 自動捕捉在編譯的時期,發現無法編譯的早期錯誤 ( early error )。
後續會再講解執行時期 ( runtime ),使用 try..catch 以外,來捕捉錯誤的規則。
var a = /+foo/; // SyntaxError
var a;
42 = a; // ReferanceError
function foo(a,b,a) {} // pass
function bar(a,b,a) {"use strict";} // SyntaxError
var a = {b:42, b:43};
a.b; // 43
(function() {
"use strict";
var m = {p:42, p:43}; // chrome 沒有錯誤不回傳,firefox 會回傳 log。
console.log(m.p); // 43
}());
最後一個物件字面值,帶名稱相同的屬性。在測試中沒發生錯誤。再請多多指教。
ES6 的新概念,導入了 TDZ ( Temporal Dead Zone )。
TDZ 代表的是某個變數的參考動作還不能進行的地方,因為該變數尚未達成必要的初始化動作。
ES6 let 的範例。
{
typeof a; // undefined
typeof b; // ReferenceError ! (TDZ)
let b;
}
function foo( a=42, b = a + b + 5 ){}
foo(); // ReferenceError
因為 b = a + b + 5
的 b 參考 會在 參數 b 的 TDZ 中發生。 但 a 就沒有問題
function foo( a = 42, b = a + 1){
console.log( a, b );
}
foo(); // 42 43
foo( undefined ); // 42 43
foo( 5 ); // 5 6
foo( void 0, 7 ); // 42 7
foo( null ); // null 1
就目前看起來沒傳值,和傳入 undefined 結果相同。
要怎麼分辨? 用 arguments。
function foo( a = 42, b = a + 1 ){
console.log(
a, b, arguments.length, arguments[0], arguments[1]
);
}
foo(); // 42 43 2 undefined undefined
foo( 10 ); // 10 11 1 10 undefined
foo( 10, undefined ); // 10 11 2 10 undefined
foo( 10, null ); // 10 null 2 10 null
foo( null, 10 ); // null 10 2 null 10
用這個方法就可以分辨傳入的參數值,他會插入 argument 陣列的插槽中。如果沒插入,不會有對應的條目 ( entries ),但會顯示 undefined。
但如果對參數在做一次 assign 呢? 他會產生連結,把值傳入 arguments,這會造成資訊洩露。
function foo(a){
a = 42;
console.log( arguments[0] );
}
foo( 2 ); // 42
foo(); // undefined
你可以使用嚴格模式避免。
function foo(a){
"use strict"
a = 42;
console.log( arguments[0] );
}
foo( 2 ); // 2
foo(); // undefined
這後面有一些 argument 陣列被棄用,以及他原先好處的描述。這邊就不贅述了。
這邊主要是介紹 finally 的用法,還有他執行時的優先順序。
Tony 歸納的規則,如下
執行 try -> 執行 finally -> 執行 loop 的迭代 -> 顯示 finally -> 顯示 try (若被覆蓋就不顯示)
套用這個規則看書上的程式碼會更有感覺。
最後,如果你想解出讓人困惑到死的程式碼,可以使用 finally 加上帶有標籤的 break 來產生取消 return 的效果。
明~天~見~